package com.ruoyi.system.utils;

import java.time.*;
import java.util.Date;

public class WorkTimeCalculator {

    private static final LocalTime WORKDAY_START = LocalTime.of(9, 0);
    private static final LocalTime WORKDAY_END = LocalTime.of(18, 0);
    private static final long MINUTES_IN_WORKDAY = Duration.between(WORKDAY_START, WORKDAY_END).toMinutes();

    public static long calculateWorkMinutesBetween(Date orderDate, Date pickupDate) {
        LocalDateTime orderTime = orderDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        LocalDateTime pickupTime = pickupDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();

        if (orderTime.isAfter(pickupTime)) {
            throw new IllegalArgumentException("下单时间不能晚于揽收时间");
        }

        long totalMinutes = 0;
        if (orderTime.toLocalDate().equals(pickupTime.toLocalDate())) {
            return calculateSameDayWorkMinutes(orderTime, pickupTime);
        }

        totalMinutes += calculateRemainingWorkMinutes(orderTime);

        totalMinutes += calculateElapsedWorkMinutes(pickupTime);

        LocalDate nextDay = orderTime.toLocalDate().plusDays(1);
        LocalDate pickupDay = pickupTime.toLocalDate();

        while (nextDay.isBefore(pickupDay)) {
            totalMinutes += MINUTES_IN_WORKDAY;
            nextDay = nextDay.plusDays(1);
        }

        return totalMinutes;
    }

    private static long calculateSameDayWorkMinutes(LocalDateTime start, LocalDateTime end) {
        LocalTime startTime = start.toLocalTime();
        LocalTime endTime = end.toLocalTime();

        if (endTime.isBefore(WORKDAY_START)) {
            return 0;
        }

        if (startTime.isAfter(WORKDAY_END)) {
            return 0;
        }
        LocalTime effectiveStart = startTime.isBefore(WORKDAY_START) ? WORKDAY_START : startTime;
        LocalTime effectiveEnd = endTime.isAfter(WORKDAY_END) ? WORKDAY_END : endTime;
        return Duration.between(effectiveStart, effectiveEnd).toMinutes();
    }

    private static long calculateRemainingWorkMinutes(LocalDateTime orderTime) {
        LocalTime orderTimeOfDay = orderTime.toLocalTime();

        if (orderTimeOfDay.isAfter(WORKDAY_END)) {
            return 0;
        }
        LocalTime effectiveStart = orderTimeOfDay.isBefore(WORKDAY_START) ? WORKDAY_START : orderTimeOfDay;
        return Duration.between(effectiveStart, WORKDAY_END).toMinutes();
    }

    private static long calculateElapsedWorkMinutes(LocalDateTime pickupTime) {
        LocalTime pickupTimeOfDay = pickupTime.toLocalTime();

        if (pickupTimeOfDay.isBefore(WORKDAY_START)) {
            return 0;
        }
        LocalTime effectiveEnd = pickupTimeOfDay.isAfter(WORKDAY_END) ? WORKDAY_END : pickupTimeOfDay;
        return Duration.between(WORKDAY_START, effectiveEnd).toMinutes();
    }

}